﻿using UnityEngine;
using UnityEngine.Events;

namespace Simulation.Framework
{
    public class AudioExtensions
    {
        public UnityAction onComplete;
        public AudioSource audioSource { get; private set; }
        public AudioType type {
            get { if (audioSource == null) { return  AudioType.EFFECT; } else { return audioSource.loop ? AudioType.BGM : AudioType.EFFECT; } }
            set { audioSource.loop = value == AudioType.BGM; }
        }

        private GameObject audioGo;
        private Timer timer;
        public AudioExtensions(AudioClip clip)
        {
            audioGo = new GameObject("effect");
            //GameObject.DontDestroyOnLoad(audioGo);
            audioSource = audioGo.AddComponent<AudioSource>();
            audioSource.clip = clip;
            audioSource.Play();
            AddTimer();
        }
        public void PlayAudio(AudioClip clip)
        {
            if (audioSource == null)
            {
                audioGo = new GameObject("effect");
            }
            audioSource = audioGo.GetOrAddComponent<AudioSource>();
            audioSource.clip = clip;
            audioSource.Play();
            AddTimer();
        }
        public void PlayVolume(float volume)
        {
            if (audioSource == null) return;
            audioSource.volume = volume;
        }
        public void Pause()
        {
            audioSource?.Pause();
            SingleBehavior<TimerManager>.getInstance().Pause(timer);
        }

        public void UnPause()
        {
            audioSource?.UnPause();
            SingleBehavior<TimerManager>.getInstance().UnPause(timer);
        }

        public void Stop()
        {
            if (audioSource) audioSource?.Stop();

            if (audioSource) Object.Destroy(audioSource);
            if (audioGo) Object.Destroy(audioGo);
            audioSource = null;
            audioGo = null;
            onComplete = null;

            SingleBehavior<TimerManager>.getInstance().RemoveTimer(timer);
        }

        private void OnComplete()
        {
            if (audioSource == null) return;
            onComplete?.Invoke();
            if (type == AudioType.BGM)
            {
                AddTimer();
                return;
            }
            if (audioSource) Object.Destroy(audioSource);
            if (audioGo) Object.Destroy(audioGo);

            audioSource = null;
            audioGo = null;
            onComplete = null;
        }

        private void AddTimer()
        {
            timer = new Timer(audioSource.clip.length);
            timer.id = audioSource.clip.name;
            timer.type =  ETimerType.FIXED;
            timer.complete = OnComplete;
            SingleBehavior<TimerManager>.getInstance().AddTimer(timer);
        }

        public enum AudioType
        {
            BGM, EFFECT
        }
    }
}